package gazzera.node.core.plugins.shareplugin.db;

import gazzera.utils.*;

import java.io.*;
import java.security.*;
import java.util.concurrent.*;

public class Hasher extends Thread {

	private BlockingQueue<String> fileToHash = new LinkedBlockingQueue<String>();
	private byte[] buf = new byte[1024*50];
	private boolean isBlocked = false;
	
	private HashDatabase db;
	
	public Hasher(HashDatabase db) 
	{
		super("Hasher");
		setDaemon(true);
		setPriority(MIN_PRIORITY);
		this.db = db;
		
	}

	public void block()
	{
		isBlocked = true;
		fileToHash.add("POISON");
	}
	
	@Override
	public void run()
	{
		try {
			while (true) {
				
				String s = fileToHash.take();
				if(isBlocked)return;
				File file = new File(s);
				Hash h = db.getHash(file, false);
				if(h.equals(Hash.EMPTY))
				{
					try {
						System.out.println("Hashing "+file.getName());
						
						Hash hash = hashFile(file);
						if(isBlocked)return;
						db.put(hash, file);
						
					} catch (Exception e) {
						System.err.println("Unable to hash "+s);
						e.printStackTrace();
					}
				}
			}
		} catch (InterruptedException e) {
			System.err.println("Hasher was interrupted");
		}
	}

	private Hash hashFile(File f) throws Exception
	{
		
		MessageDigest m = MessageDigest.getInstance("SHA1");
		FileInputStream fis = new FileInputStream(f);
		try
		{
			int r = fis.read(buf);
			while (r>=0)
			{
				m.update(buf, 0, r);
				r = fis.read(buf);
				
				if(isBlocked)return Hash.EMPTY;
			}
			return new Hash(m.digest());
		}
		finally
		{
			fis.close();
		}
	}
	
	public void addFileToHash(String filename)
	{
		//if(!fileToHash.contains(filename))
		
			if(fileToHash.size()>1000) return;
			fileToHash.add(filename);
		
		
	}
	public void clean()
	{
		fileToHash.clear();
		
	}
	
	
	
}
